import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.*;
import java.awt.*;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SyntaxHighlighterTextArea extends JTextPane {
    // 定义关键字
    private static final String[] KEYWORDS = {
        "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class",
        "const", "continue", "default", "do", "double", "else", "enum", "extends", "final",
        "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", 
        "int", "interface", "long", "native", "new", "package", "private", "protected", 
        "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", 
        "this", "throw", "throws", "transient", "try", "void", "volatile", "while", "true", 
        "false", "null"
    };
    
    // 定义样式
    private Style keywordStyle;
    private Style stringStyle;
    private Style commentStyle;
    private Style normalStyle;
    
    // 控制语法高亮的标志
    private boolean highlightingEnabled = true;
    private Timer highlightTimer;
    private Set<Integer> linesToHighlight = new HashSet<>();
    
    public SyntaxHighlighterTextArea() {
        super();
        initStyles();
        addTextChangedListener();
    }
    
    private void initStyles() {
        StyledDocument doc = getStyledDocument();
        
        // 关键字样式（蓝色粗体）
        keywordStyle = doc.addStyle("keyword", null);
        StyleConstants.setForeground(keywordStyle, Color.BLUE);
        StyleConstants.setBold(keywordStyle, true);
        
        // 字符串样式（红色）
        stringStyle = doc.addStyle("string", null);
        StyleConstants.setForeground(stringStyle, new Color(128, 0, 0));
        
        // 注释样式（灰色斜体）
        commentStyle = doc.addStyle("comment", null);
        StyleConstants.setForeground(commentStyle, Color.GRAY);
        StyleConstants.setItalic(commentStyle, true);
        
        // 普通文本样式（黑色）
        normalStyle = doc.addStyle("normal", null);
        StyleConstants.setForeground(normalStyle, Color.BLACK);
        StyleConstants.setBold(normalStyle, false);
        StyleConstants.setItalic(normalStyle, false);
    }
    
    private void addTextChangedListener() {
        getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                scheduleHighlight();
            }
            
            @Override
            public void removeUpdate(DocumentEvent e) {
                scheduleHighlight();
            }
            
            @Override
            public void changedUpdate(DocumentEvent e) {
                scheduleHighlight();
            }
        });
    }
    
    // 延迟执行语法高亮，避免频繁触发
    private void scheduleHighlight() {
        if (!highlightingEnabled) return;
        
        if (highlightTimer != null && highlightTimer.isRunning()) {
            highlightTimer.restart();
        } else {
            highlightTimer = new Timer(300, e -> {
                highlightSyntax();
                highlightTimer = null;
            });
            highlightTimer.setRepeats(false);
            highlightTimer.start();
        }
    }
    
    // 禁用语法高亮（用于加载大文件时）
    public void setHighlightingEnabled(boolean enabled) {
        this.highlightingEnabled = enabled;
    }
    
    private void highlightSyntax() {
        if (!highlightingEnabled) return;
        
        StyledDocument doc = getStyledDocument();
        String text;
        try {
            text = doc.getText(0, doc.getLength());
        } catch (BadLocationException e) {
            return;
        }
        
        // 重置所有文本为普通样式
        doc.setCharacterAttributes(0, text.length(), normalStyle, true);
        
        // 高亮注释
        highlightPattern(doc, text, "//.*", commentStyle);  // 单行注释
        highlightPattern(doc, text, "/\\*[\\s\\S]*?\\*/", commentStyle);  // 多行注释
        
        // 高亮字符串
        highlightPattern(doc, text, "\"([^\"\\\\]|\\\\.)*\"", stringStyle);  // 双引号字符串
        highlightPattern(doc, text, "'([^'\\\\]|\\\\.)*'", stringStyle);     // 单引号字符
        
        // 高亮关键字
        for (String keyword : KEYWORDS) {
            highlightPattern(doc, text, "\\b" + keyword + "\\b", keywordStyle);
        }
    }
    
    private void highlightPattern(StyledDocument doc, String text, String pattern, Style style) {
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(text);
        
        while (m.find()) {
            doc.setCharacterAttributes(m.start(), m.end() - m.start(), style, false);
        }
    }
}